package com.letoken.platform.app.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.letoken.platform.app.service.AppUserIssueHistoryService;
import com.letoken.platform.app.service.LetokenUserService;
import com.letoken.platform.pub.annotation.auth.NotAuthorization;
import com.letoken.platform.pub.annotation.pub.Trim;
import com.letoken.platform.pub.constant.ConstantsValue;
import com.letoken.platform.pub.req.PageData;
import com.letoken.platform.pub.req.QueryReqBase;
import com.letoken.platform.pub.res.ApiResponse;
import com.letoken.platform.pub.util.DataCalculationUtils;
import com.letoken.platform.pub.util.DateUtil;
import com.letoken.platform.pub.util.LocalDateTool;
import com.letoken.platform.repo.app.dao.AppUserIssueHistoryMapper;
import com.letoken.platform.repo.app.req.user.*;
import com.letoken.platform.repo.app.res.config.AmbHistoryRes;
import com.letoken.platform.repo.app.res.config.QueryLetokenHistoryRes;
import com.letoken.platform.repo.app.res.token.WaitCirculationRes;
import com.letoken.platform.repo.app.res.user.QueryAddressTokenRes;
import com.letoken.platform.repo.app.res.user.QueryAmbassadorEquityRes;
import com.letoken.platform.repo.app.res.user.QueryAppUserRes;
import com.letoken.platform.repo.mall.dao.*;
import com.letoken.platform.repo.mall.po.*;
import com.letoken.platform.repo.mall.res.CirculationRes;
import com.letoken.platform.repo.utlis.PageDataUtil;
import com.letoken.platform.repo.utlis.WebUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author letokenlabs
 * @date 2022/11/12$
 */
@RestController
@RequestMapping("/user")
@Api(tags = "我的-用户接口", description = "App用户接口")
public class LetokenUserController {

    @Autowired
    private LetokenUserService letokenUserService;
    @Autowired
    AppMallAmbassadorRecordMapper appMallAmbassadorRecordMapper;
    @Autowired
    AdminMallIssueConfigMapper adminMallIssueConfigMapper;
    @Autowired
    AppMallAmbSummaryMapper appMallAmbSummaryMapper;
    @Autowired
    AppMallAmbassadorHistoryMapper appMallAmbassadorHistoryMapper;
    @Autowired
    AdminMallAmbassadorMapper adminMallAmbassadorMapper;

    @GetMapping("/")
    @ApiOperation(value = "查询用户信息", notes = "查询用户信息")
    public ApiResponse<QueryAppUserRes> queryAppUser() {
        return ApiResponse.create(letokenUserService.queryAppUser());
    }

    @GetMapping("/invitecode")
    @ApiOperation(value = "查询用户的邀请码", notes = "查询用户的邀请码")
    public ApiResponse<String> queryAppUserInviteCode() {
        return ApiResponse.create(letokenUserService.queryAppUserInviteCode());
    }

    @GetMapping("/token/list")
    @ApiOperation(value = "查询用户代币信息查询", notes = "查询用户代币信息查询")
    public ApiResponse<List<QueryAddressTokenRes>> queryAddressToken(@RequestBody @Validated QueryAddressTokenReq req) {
        return ApiResponse.create(letokenUserService.queryAddressToken(req));
    }

    @Trim
    @PostMapping("/update/username")
    @ApiOperation(value = "修改用户名", notes = "修改昵称")
    public ApiResponse updateUserName(@RequestBody @Validated UpdateUserNameReq req) {
        letokenUserService.updateUserName(req);
        return ApiResponse.create();
    }

    @PostMapping(value = "/update/headimage")
    @ApiOperation(value = "修改头像", notes = "修改头像")
    public ApiResponse updateUserHeadImage(@RequestPart("file") MultipartFile file) {
        String url = letokenUserService.updateUserHeadImage(file);
        return ApiResponse.create(url);
    }



    @GetMapping(value = "/ambassador/equity")
    @ApiOperation(value = "推广大使权益", notes = "推广大使权益")
    public ApiResponse<QueryAmbassadorEquityRes> ambassadorEquity() {
        return ApiResponse.create(letokenUserService.ambassadorEquity());
    }

    @NotAuthorization
    @GetMapping(value = "/ambassador/equityList")
    @ApiOperation(value = "推广大使权益列表", notes = "推广大使权益列表")
    public ApiResponse<List<QueryAmbassadorEquityRes.AdminMallAmbassadorVo>> ambassadorEquityList() {
        LambdaQueryWrapper<AdminMallAmbassador> lqwAma = new LambdaQueryWrapper<>();
        lqwAma.eq(AdminMallAmbassador::getState, ConstantsValue.I_0)
                .select(AdminMallAmbassador::getBonus,AdminMallAmbassador::getEco,AdminMallAmbassador::getLevel,AdminMallAmbassador::getLevelName)
                .orderByAsc(AdminMallAmbassador::getLevel);
        List<AdminMallAmbassador> equityList = adminMallAmbassadorMapper.selectList(lqwAma);
        if (CollectionUtils.isEmpty(equityList)){
            return ApiResponse.create(new ArrayList<>());
        }
        return ApiResponse.create(equityList.stream().map(x->{
            QueryAmbassadorEquityRes.AdminMallAmbassadorVo vo = new QueryAmbassadorEquityRes.AdminMallAmbassadorVo();
            BeanUtils.copyProperties(x,vo);
            return vo;
        }).collect(Collectors.toList()));
    }




    @GetMapping("/ambassador/waitCirculation")
    @ApiOperation(value = "推广大使-生态分红流通", notes = "推广大使-生态分红流通")
    public ApiResponse<CirculationRes> queryWaitCirculation() {
        Integer userId = WebUtils.getUserId();
        LambdaQueryWrapper<AppMallAmbassadorRecord> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(AppMallAmbassadorRecord::getUserId, userId)
                .eq(AppMallAmbassadorRecord::getStatus, 0)
                .gt(AppMallAmbassadorRecord::getWaitCirculation, 0)
                .orderByDesc(AppMallAmbassadorRecord::getCreateTime);
        List<AppMallAmbassadorRecord> issueRecordsList = appMallAmbassadorRecordMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(issueRecordsList)) {
            return ApiResponse.create(new CirculationRes());
        }
        LambdaQueryWrapper<AppMallAmbSummary> lqwAma = new LambdaQueryWrapper<>();
        lqwAma.eq(AppMallAmbSummary::getUserId,userId);
        AppMallAmbSummary appMallIssue = appMallAmbSummaryMapper.selectOne(lqwAma);
        if (appMallIssue.getCirculationRemain().compareTo(BigDecimal.ZERO) <= 0) {
            return ApiResponse.create(new CirculationRes());
        }

        Duration duration = Duration.between(appMallIssue.getRewardTime().plusMinutes(appMallIssue.getCountDown()), LocalDateTime.now());
        //距离下个周期释放时间
        Integer down = (Math.abs((int) duration.toMinutes()));
        LocalDateTime oneRoundTime = appMallIssue.getRewardTime().plusMinutes(appMallIssue.getCountDown());
        List<WaitCirculationRes> waitCirculationResList = new ArrayList<>();
        AdminMallIssueConfig config = adminMallIssueConfigMapper.selectById(1);
        for (AppMallAmbassadorRecord record : issueRecordsList) {
            int cycle =  DataCalculationUtils.ambCalculationPeriod(record.getAmount(),record.getContributing(),config.getCirculationRate());
            // 计算每期释放额度
            BigDecimal amount = record.getTotalCirculation().divide(new BigDecimal(cycle), 10, RoundingMode.HALF_UP);

            BigDecimal lave = record.getWaitCirculation();
            // int count = cycle.intValue();
            for (int i = 0; i < 50; i++) {
                if (lave.compareTo(BigDecimal.ZERO) <= 0){
                    break;
                }
                WaitCirculationRes waitCirculationRes = new WaitCirculationRes();
                waitCirculationRes.setRound(i + 1);
                waitCirculationRes.setDateTime(oneRoundTime);
                if (i < waitCirculationResList.size()) {
                    waitCirculationResList.get(i).setLetNum(waitCirculationResList.get(i).getLetNum().add(amount));
                } else {
                    waitCirculationRes.setLetNum(amount);
                    waitCirculationResList.add(waitCirculationRes);
                }
                lave = lave.subtract(amount);
                oneRoundTime = oneRoundTime.plusDays(config.getCountDown());
            }

        }


        CirculationRes circulationRes = new CirculationRes();
        circulationRes.setList(waitCirculationResList);
        circulationRes.setAmount(appMallIssue.getCirculationRemain().setScale(8,RoundingMode.FLOOR));
        circulationRes.setCountDown(down);
        if (CollectionUtils.isNotEmpty(circulationRes.getList())){
            circulationRes.getList().forEach(x->{
                x.setLetNum(x.getLetNum().setScale(8,RoundingMode.FLOOR));
            });
        }
        return ApiResponse.create(circulationRes);
    }


    @GetMapping("/ambassador/bonusData")
    @ApiOperation(value = "待流通记录分红统计", notes = "待流通记录分红统计")
    public ApiResponse<BigDecimal> ambRecords(@ApiParam(name = "date", value = "2023-06-01") @RequestParam("date") String date ) {
        LocalDateTime useDate ;
        if (ObjectUtils.isEmpty(date)){
            useDate = LocalDateTime.now();
        }else {
            date = date + " 00:00:00";
            useDate = LocalDateTool.strToLocalDateTime(date,LocalDateTool.yyyyMMddHHmmss);
        }
        LocalDateTime start = LocalDateTool.plusDay(useDate,0);
        LocalDateTime end = LocalDateTool.plusDay(useDate,1);
        Integer userId = WebUtils.getUserId();
        BigDecimal a = appMallAmbassadorHistoryMapper.ambRecordData(userId,start,end);
        return ApiResponse.create(a);
    }

    @PostMapping("/ambassador/records")
    @ApiOperation(value = "推广大使-待流通记录", notes = "推广大使-待流通记录")
    public ApiResponse<PageData<AmbHistoryRes>> ambRecords(@RequestBody @Validated AbmRecordsReq req) {
        LocalDateTime useDate ;
        if (ObjectUtils.isEmpty(req.getDate())){
            useDate = LocalDateTime.now();
        }else {
            req.setDate(req.getDate() + " 00:00:00");
            useDate = LocalDateTool.strToLocalDateTime(req.getDate(),LocalDateTool.yyyyMMddHHmmss);
        }
        LocalDateTime start = LocalDateTool.plusDay(useDate,0);
        LocalDateTime end = LocalDateTool.plusDay(useDate,1);
        Integer userId = WebUtils.getUserId();
        Page<AmbHistoryRes> page = new Page<>(req.getPageReq().getPage(),req.getPageReq().getSize());
        return ApiResponse.create(appMallAmbassadorHistoryMapper.ambRecords(page,userId,start,end));
    }






}
